/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package BoardGameLanguage.impl;

import BoardGameLanguage.Board;
import BoardGameLanguage.BoardGameLanguagePackage;
import BoardGameLanguage.Field;
import BoardGameLanguage.Figure;

import de.upb.tools.fca.*;
import de.upb.tools.sdm.*;

import java.lang.reflect.InvocationTargetException;

import java.util.*;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;

import org.eclipse.emf.ecore.util.EcoreUtil;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Figure</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link BoardGameLanguage.impl.FigureImpl#getField <em>Field</em>}</li>
 *   <li>{@link BoardGameLanguage.impl.FigureImpl#getBoard <em>Board</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public abstract class FigureImpl extends EObjectImpl implements Figure {
	/**
	 * The cached value of the '{@link #getField() <em>Field</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getField()
	 * @generated
	 * @ordered
	 */
	protected Field field;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FigureImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return BoardGameLanguagePackage.Literals.FIGURE;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Field getField() {
		if (field != null && field.eIsProxy()) {
			InternalEObject oldField = (InternalEObject) field;
			field = (Field) eResolveProxy(oldField);
			if (field != oldField) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE,
							BoardGameLanguagePackage.FIGURE__FIELD, oldField,
							field));
			}
		}
		return field;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Field basicGetField() {
		return field;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetField(Field newField,
			NotificationChain msgs) {
		Field oldField = field;
		field = newField;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this,
					Notification.SET, BoardGameLanguagePackage.FIGURE__FIELD,
					oldField, newField);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setField(Field newField) {
		if (newField != field) {
			NotificationChain msgs = null;
			if (field != null)
				msgs = ((InternalEObject) field).eInverseRemove(this,
						BoardGameLanguagePackage.FIELD__FIGURE, Field.class,
						msgs);
			if (newField != null)
				msgs = ((InternalEObject) newField).eInverseAdd(this,
						BoardGameLanguagePackage.FIELD__FIGURE, Field.class,
						msgs);
			msgs = basicSetField(newField, msgs);
			if (msgs != null)
				msgs.dispatch();
		} else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET,
					BoardGameLanguagePackage.FIGURE__FIELD, newField, newField));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Board getBoard() {
		if (eContainerFeatureID() != BoardGameLanguagePackage.FIGURE__BOARD)
			return null;
		return (Board) eContainer();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetBoard(Board newBoard,
			NotificationChain msgs) {
		msgs = eBasicSetContainer((InternalEObject) newBoard,
				BoardGameLanguagePackage.FIGURE__BOARD, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBoard(Board newBoard) {
		if (newBoard != eInternalContainer()
				|| (eContainerFeatureID() != BoardGameLanguagePackage.FIGURE__BOARD && newBoard != null)) {
			if (EcoreUtil.isAncestor(this, newBoard))
				throw new IllegalArgumentException(
						"Recursive containment not allowed for " + toString());
			NotificationChain msgs = null;
			if (eInternalContainer() != null)
				msgs = eBasicRemoveFromContainer(msgs);
			if (newBoard != null)
				msgs = ((InternalEObject) newBoard).eInverseAdd(this,
						BoardGameLanguagePackage.BOARD__FIGURES, Board.class,
						msgs);
			msgs = basicSetBoard(newBoard, msgs);
			if (msgs != null)
				msgs.dispatch();
		} else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET,
					BoardGameLanguagePackage.FIGURE__BOARD, newBoard, newBoard));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void move(Field targetField) {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void performMove(Field targetField) {
		boolean fujaba__Success = false;
		Field currentField = null;

		// story pattern ActivityNode4
		try {
			fujaba__Success = false;

			// check object targetField is really bound
			JavaSDM.ensure(targetField != null);
			// bind object
			currentField = this.getField();

			// check object currentField is really bound
			JavaSDM.ensure(currentField != null);

			// check isomorphic binding between objects targetField and currentField
			JavaSDM.ensure(!targetField.equals(currentField));

			// destroy link
			currentField.setFigure(null);
			// create link
			targetField.setFigure(this);

			fujaba__Success = true;
		} catch (JavaSDMException fujaba__InternalException) {
			fujaba__Success = false;
		}

		return;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
		case BoardGameLanguagePackage.FIGURE__FIELD:
			if (field != null)
				msgs = ((InternalEObject) field).eInverseRemove(this,
						BoardGameLanguagePackage.FIELD__FIGURE, Field.class,
						msgs);
			return basicSetField((Field) otherEnd, msgs);
		case BoardGameLanguagePackage.FIGURE__BOARD:
			if (eInternalContainer() != null)
				msgs = eBasicRemoveFromContainer(msgs);
			return basicSetBoard((Board) otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
		case BoardGameLanguagePackage.FIGURE__FIELD:
			return basicSetField(null, msgs);
		case BoardGameLanguagePackage.FIGURE__BOARD:
			return basicSetBoard(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eBasicRemoveFromContainerFeature(
			NotificationChain msgs) {
		switch (eContainerFeatureID()) {
		case BoardGameLanguagePackage.FIGURE__BOARD:
			return eInternalContainer().eInverseRemove(this,
					BoardGameLanguagePackage.BOARD__FIGURES, Board.class, msgs);
		}
		return super.eBasicRemoveFromContainerFeature(msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
		case BoardGameLanguagePackage.FIGURE__FIELD:
			if (resolve)
				return getField();
			return basicGetField();
		case BoardGameLanguagePackage.FIGURE__BOARD:
			return getBoard();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
		case BoardGameLanguagePackage.FIGURE__FIELD:
			setField((Field) newValue);
			return;
		case BoardGameLanguagePackage.FIGURE__BOARD:
			setBoard((Board) newValue);
			return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
		case BoardGameLanguagePackage.FIGURE__FIELD:
			setField((Field) null);
			return;
		case BoardGameLanguagePackage.FIGURE__BOARD:
			setBoard((Board) null);
			return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
		case BoardGameLanguagePackage.FIGURE__FIELD:
			return field != null;
		case BoardGameLanguagePackage.FIGURE__BOARD:
			return getBoard() != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eInvoke(int operationID, EList<?> arguments)
			throws InvocationTargetException {
		switch (operationID) {
		case BoardGameLanguagePackage.FIGURE___MOVE__FIELD:
			move((Field) arguments.get(0));
			return null;
		case BoardGameLanguagePackage.FIGURE___PERFORM_MOVE__FIELD:
			performMove((Field) arguments.get(0));
			return null;
		}
		return super.eInvoke(operationID, arguments);
	}

} //FigureImpl
